import numpy as np
import pandas as pd

from src.utils.config import config, logger
from src.tablet.model import tablet_model_config
from src.tablet.preprocessor import prop_preprocessor as prop
from src.utils.model_utils import cal_period, load_sku_property
import time

# 手机SKU属性在redis中key的前缀
TABLET_REDIS_PREFIX_KEY = config.get_config('project', 'tablet_redis_prefix_key')


def preprocess_model_data(data, is_cal_period=True):
    """
    预处理成模型数据
    :param data: 原始数据
    :param is_cal_period: 是否计算周期
    :return:
    """
    model_data = data.rename(columns=tablet_model_config.TABLET_COLUMNS_MAPPING).copy()

    # 将memory字段为memory+storage形式的拆分为memory和storage字段
    memory_storage_split = model_data['memory'].str.split('+', expand=True)
    if memory_storage_split.shape[1] == 1:
        # 如果只分出来一个字段，那么补上一个
        memory_storage_split.columns = ['memory_tmp']
        memory_storage_split['storage_tmp'] = np.nan
    else:
        memory_storage_split.columns = ['memory_tmp', 'storage_tmp']
    model_data = pd.concat([model_data, memory_storage_split], axis=1, sort=False)
    model_data['memory'] = model_data['memory_tmp']
    model_data['storage'] = model_data['storage'].where(pd.isnull(model_data['storage_tmp']), model_data['storage_tmp'])
    model_data = model_data.drop(columns=['memory_tmp', 'storage_tmp'])

    # 将苹果手机的内存字段设置为特定字符以区分其他手机没有内存为unknown的情况
    model_data.loc[model_data['product_brand_name'] == '苹果', 'memory'] = prop.APPLE_MEMORY_FLAG

    if is_cal_period:
        model_data['period'] = model_data['settle_list_create_date'].apply(cal_period, interval=7).astype(str)

    return model_data


def process_predict_data(data, process_level=True):
    """
    预处理传入的预测数据
    :param data: 数据
    :param process_level: 是否处理等级
    :return:
    """
    logger.info('processing predict data')
    # sku_property = load_sku_property(data, TABLET_REDIS_PREFIX_KEY, tablet_model_config.TABLET_COLUMNS_MAPPING)

    t0=time.time()
    try:
        ti1 = time.time()
        sku_property = load_sku_property(data, TABLET_REDIS_PREFIX_KEY, tablet_model_config.TABLET_COLUMNS_MAPPING)
        logger.info('load_sku_property use time @{}'.format(time.time() - ti1))
    except Exception as e:
        logger.info('load_sku_property timeout@{}'.format(e))
        sku_property=[]
    logger.info('load_sku_property use time@{}'.format(time.time() - t0))

    if sku_property is None or len(sku_property)==0:
        predict_data = pd.DataFrame()
        return predict_data

    # 检查特征是否完整
    predict_data = pd.DataFrame(sku_property)
    for feature in tablet_model_config.TABLET_FEATURES:
        if feature not in predict_data:
            predict_data[feature] = 'unknown'
    # 检查是否有product_id，如果没有，增加product_id，默认为0
    if 'product_id' not in predict_data:
        predict_data['product_id'] = 0
    # 将缺失值用unknown填补
    predict_data.fillna('unknown', inplace=True)
    predict_data['product_level_template_id'] = predict_data['product_level_template_id'].astype(str)

    if process_level:
        predict_data['product_level_name'] = predict_data['level_id'].copy()
        predict_data['product_level_name'] = predict_data['product_level_name'].replace(
            tablet_model_config.TABLET_LEVEL_ID_MAPPING).astype(str)
    logger.info('preprocess model data')
    predict_data = preprocess_model_data(predict_data, is_cal_period=False)

    return predict_data
